#include "apdu_key_manager.h"

#include "../../mk_lib/mk_utility.h"

#include <string.h>
#include <memory.h>
#include <stdlib.h>

apdu_key_manager::apdu_key_manager( void )
{

}

apdu_key_manager::~apdu_key_manager( void )
{

}


apdu * apdu_key_manager::create_apdu_export_public_key( int app_id, int container_id, int key_type )
{
	apdu * newApdu = new apdu(SC_APDU_CASE_4_EXT, 0x80, 0x88, key_type,0x00, "ExportPublicKey");

	unsigned char data[4096] = {0};

	int pos = 0;
	mk_utility::fill_buff_with_word_value_be(app_id, data);
	pos += 2;

	mk_utility::fill_buff_with_word_value_be(container_id, data + pos);
	pos += 2;

	newApdu->set_lc_data(data, pos);

	return newApdu;
}

apdu * apdu_key_manager::create_apdu_import_session_key( int app_id, int container_id, int key_spec, unsigned long alg_id,
														unsigned char * wraped_data, unsigned long wraped_len )
{
	apdu * newApdu = new apdu(SC_APDU_CASE_4_EXT, 0x80, 0xA0, key_spec,0x00, "ImportSessionKey");

	unsigned char data[4096] = {0};

	int pos = 0;
	mk_utility::fill_buff_with_word_value_be(app_id, data);
	pos += 2;

	mk_utility::fill_buff_with_word_value_be(container_id, data + pos);
	pos += 2;

	mk_utility::fill_buff_with_dword_value_be(alg_id, data + pos);
	pos += 4;

	mk_utility::fill_buff_with_dword_value_be(wraped_len, data + pos);
	pos += 4;
	
	memcpy(data + pos, wraped_data, wraped_len);
	pos += wraped_len;

	newApdu->set_lc_data(data, pos);

	return newApdu;
}

apdu * apdu_key_manager::create_apdu_destroy_session_key( int app_id, int container_id, int key_id )
{
	apdu * newApdu = new apdu(SC_APDU_CASE_3_EXT, 0x80, 0xC4, 0, 0, "DestroySessionKey");
	unsigned char data[4096] = {0};

	int pos = 0;
	mk_utility::fill_buff_with_word_value_be(app_id, data);
	pos += 2;

	mk_utility::fill_buff_with_word_value_be(container_id, data + pos);
	pos += 2;

	mk_utility::fill_buff_with_word_value_be(key_id, data + pos);
	pos += 2;

	newApdu->set_lc_data(data, pos);

	return newApdu;
}

apdu * apdu_key_manager::create_apdu_gen_session_key(int app_id, int container_id, unsigned long alg_id )
{
	apdu * newApdu = new apdu(SC_APDU_CASE_4_EXT, 0xC0, 0x10, 0x00,0x00, "SetSessionKey");

	unsigned char data[64] = {0};

	int pos = 0;

	mk_utility::fill_buff_with_word_value_be(app_id, data);
	pos += 2;

	mk_utility::fill_buff_with_word_value_be(container_id, data + pos);
	pos += 2;

	mk_utility::fill_buff_with_dword_value_be(alg_id, data + pos);
	pos += 4;

	newApdu->set_lc_data(data, pos);

	return newApdu;
}

apdu * apdu_key_manager::create_apdu_set_session_key(int app_id, int container_id, unsigned long alg_id,
													 unsigned char * key_value, int len )
{
	apdu * newApdu = new apdu(SC_APDU_CASE_4_EXT, 0xC0, 0x12, 0x00, 0x00, "SetSessionKey");

	unsigned char data[128] = {0};

	int pos = 0;

	mk_utility::fill_buff_with_word_value_be(app_id, data);
	pos += 2;

	mk_utility::fill_buff_with_word_value_be(container_id, data + pos);
	pos += 2;

	mk_utility::fill_buff_with_dword_value_be(alg_id, data + pos);
	pos += 4;

	if(len > 32) len = 32;
	memcpy(data + pos, key_value, len);
	pos += 32;

	newApdu->set_lc_data(data, pos);

	return newApdu;
}

apdu * apdu_key_manager::create_apdu_set_session_key_from_file( int app_id, int container_id, unsigned long alg_id, 
															   int offset, char * file_name )
{
	apdu * newApdu = new apdu(SC_APDU_CASE_4_EXT, 0xC0, 0x12, 0x01, 0x00, "SetSessionKeyFromFile");

	unsigned char data[128] = {0};

	int pos = 0;

	mk_utility::fill_buff_with_word_value_be(app_id, data);
	pos += 2;

	mk_utility::fill_buff_with_word_value_be(container_id, data + pos);
	pos += 2;

	mk_utility::fill_buff_with_dword_value_be(alg_id, data + pos);
	pos += 4;
	
	mk_utility::fill_buff_with_word_value_be(offset, data + pos);
	pos += 2;

	int name_len = strlen(file_name);
	mk_utility::fill_buff_with_word_value_be(name_len, data + pos);
	pos += 2;

	memcpy(data + pos, file_name, name_len);
	pos += name_len;


	newApdu->set_lc_data(data, pos);

	return newApdu;
}

